#pragma once
#include <iostream>
#include <opencv2/opencv.hpp>
#include <unordered_map>
#include <vector>
using namespace std;
// 计算频率的输入/输出
typedef struct _FrequencyResult {
  cv::Rect rt;
  // int nCount;
} FrequencyResult;

typedef struct _FrequencyInput {
  cv::Rect rt;
  // other data
} FrequencyInput;

// 计算最大频率
class Frequency {
public:
  // 最多50
  Frequency(int nCount = 50) { this->nCount = nCount; }

public:
  const int nBIN = 5;

  int nCount;
  std::vector<FrequencyInput> arrInput;
  void reset() { arrInput.erase(arrInput.begin(), arrInput.end()); }

  // void detectFrequency(FData input) { detectFrequency(input.data); }

  FrequencyResult detectFrequency(FrequencyInput input) {
    arrInput.push_back(input);
    if (arrInput.size() < nCount) {
      return FrequencyResult();
    }

    return detectFrequencyForce();
  }

  // 检测一段时间输入的最大频率数
  FrequencyResult detectFrequencyForce() {
    // 面积大于阈值情形 这段时间内只出现3次
    if (arrInput.size() < 3) {
      return FrequencyResult();
    }

    auto fn = [](FrequencyInput input1, FrequencyInput input2) {
      return input1.rt.area() < input2.rt.area();
    };

    // 得到最大值/最小值
    auto max_iter = max_element(std::begin(arrInput), std::end(arrInput), fn);
    auto min_iter = min_element(std::begin(arrInput), std::end(arrInput), fn);
    auto max = *max_iter;
    auto min = *min_iter;
    int nHistSize = (max.rt.area() - min.rt.area()) / nBIN;

    // 最大值/最小值相同
    if (nHistSize == 0) {
      cout << "array input size:" << arrInput.size() << endl;
      reset();

      FrequencyResult res;
      res.rt = min.rt;
      return res;
    }

    std::vector<int> arrHist;
    for (auto &num : arrInput) {
      auto hist = (num.rt.area() - min.rt.area()) / nHistSize;
      arrHist.push_back(hist);
    }

    std::unordered_map<int, int> hash_table;
    for (auto &i : arrHist) {
      hash_table[i]++;
    }
    // Find the value with the maximum frequency
    int max_freq = -1, most_freq_val = -1; // Initialize these values to -1
    for (auto &i : hash_table) {
      if (i.second > max_freq) {
        max_freq = i.second;
        most_freq_val = i.first;
      }
    }

    // 这里可以提高效率，暂时采用重新查找方式，
    for (auto &num : arrInput) {
      auto hist = (num.rt.area() - min.rt.area()) / nHistSize;
      if (hist == most_freq_val) {
        // 先重置
        reset();

        FrequencyResult fr;
        fr.rt = num.rt;
        return fr;
      }
    }

    return FrequencyResult();
  }
};